﻿using BLToolkit.Data.Linq;
using CommonHelper;
using CommonLibrary;
using CommonLibrary.Models;
using CommonLibrary.Web;
using CommonSite.Areas.Admin.Models;
using CommonSite.Common;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.Mvc;

namespace CommonSite.Controllers
{
    public class AccountController : Controller
    {
        //
        // GET: /Admin/Account/
        [HttpGet]
        public ActionResult Login(string ret)
        {
            if (this.Request.Browser.IsMobileDevice)
            { 
            }

            if (this.Request.Cookies["login_name"] != null)
            {
                this.ViewBag.LoginName = this.Request.Cookies["login_name"].Value;
            }

            return View();
        }

        [HttpPost]
        public ActionResult Login(UserAccount account)
        {
            this.ViewBag.Message = null;

            if (!this.TryValidateModel(account))
            {
                this.ViewBag.Message = "用户名或密码不能为空";
                return View();
            }

            if (!UserAction.Login(account.Name, account.Password))
            {
                this.ViewBag.LoginName = account.Name;
                this.ViewBag.Message = "用户名或密码错误";
                return View();
            }

            this.Response.SetCookie(new System.Web.HttpCookie("login_name", account.Name));

            if (!account.ret.IsNullOrWhiteSpace())
                return Redirect(account.ret);
            return RedirectToAction("Index", "Home");
        }

        public ActionResult Logout()
        {
            this.Response.CacheControl = "no-cache";
            UserAction.Logout();
            return Redirect("/Account/Login");
        }

        public ActionResult Install(string app)
        {
            if (app == "d63302a9-e360-4d7e-a78e-87a439cb5685")
            {
                using (CommonDatabase db = new CommonDatabase(CommonOption.ReadWrite))
                {
                    var md5 = MD5.Create();
                    var password = "admin";
                    var salt = "abcdefghigklmnopqrstuvwxyz0123456789!@#$%^&*()".GenerateRandomString(6);
                    var buffer = md5.ComputeHash(Encoding.UTF8.GetBytes("admin" + password + salt));
                    db.sys_User.Where(k => k.Id == 1)
                      .Set(k => k.Password, buffer.ToHexString())
                      .Set(k => k.Salt, salt)
                      .Update();
                }
            }

            return RedirectToAction("Login");
        }

        [HttpGet]
        [UserAuthorizeAttribute]
        public ActionResult ChangePassword()
        {
            return View();
        }

        [HttpPost]
        [UserAuthorizeAttribute]
        public ActionResult ChangePassword(string _old, string _new, string _confrim)
        {
            using (CommonDatabase db = new CommonDatabase(CommonOption.ReadWrite))
            {
                var user = db.sys_User.Where(k => k.Id == UserAction.GetCurrentUser().UserId).First();
                if (!UserAction.CheckPassword(user, _old))
                {
                    ViewBag.Message = "当前密码错误";
                    return View();
                }

                var regex = new Regex(@"^[\@A-Za-z0-9\!\#\$\%\^\&\*\.\~]{4,16}$");
                if (!regex.IsMatch(_new))
                {
                    ViewBag.Message = "新密码格式不正确";
                    return View();
                }

                if (_new != _confrim)
                {
                    ViewBag.Message = "两次输入密码不一致";
                    return View();
                }

                db.BeginTransaction();
                string encrypt;
                string salt;
                UserAction.EncryptPassword(user.LoginName, _new, out encrypt, out salt);

                db.sys_User.Where(k => k.Id == user.Id)
                  .Set(k => k.Password, encrypt)
                  .Set(k => k.Salt, salt)
                  .Set(k => k.UpdatedTime, Sql.GetDate())
                  .Update();
                db.CommitTransaction();
            }

            return RedirectToAction("Logout");
        }

        [HttpGet]
        public ActionResult Code()
        {
            this.Response.CacheControl = "No-Cache";

            string code = GenerateCode();
            this.Session["loginCode"] = new Tuple<string, DateTime>(code, DateTime.Now);


            return File(CreateGraphic(code), "image/jpeg");
        }

        #region Helper Methods

        private static char[] codes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToArray();

        private static string GenerateCode(int length = 4)
        {
            StringBuilder sb = new StringBuilder();

            Random random = new Random((int)DateTime.Now.Ticks);
            for (int i = 0; i < length; i++)
            {
                sb.Append(codes[random.Next(codes.Length)]);
            }

            return sb.ToString();
        }

        private static byte[] CreateGraphic(string code)
        {
            using (Bitmap bmp = new Bitmap(150, 50))
            using (MemoryStream ms = new MemoryStream())
            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.FillRectangle(Brushes.White, 0, 0, 150, 50);

                int offset = 10;
                foreach (var c in code)
                {
                    g.DrawString(
                        c.ToString(),
                        new Font(FontFamily.GenericSansSerif, 36, FontStyle.Bold),
                        Brushes.Black,
                        new PointF(offset, 0));
                    offset += 20;
                }

                bmp.Save(ms, ImageFormat.Jpeg);
                return ms.ToArray();
            }
        }

        #endregion
    }
}
